package com.gdssoft.pdaweb.jobs;

import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.gdssoft.core.util.DateUtil;
import com.gdssoft.pdaweb.dao.am.AmMonthPlanDao;
import com.gdssoft.pdaweb.dao.am.AmMonthPlanReadDao;
import com.gdssoft.pdaweb.dao.am.AmPlanDao;
import com.gdssoft.pdaweb.dao.am.PdaAmMeterListDao;
import com.gdssoft.pdaweb.dao.water.PdaWaterListDao;
import com.gdssoft.pdaweb.dao.water.WaterMeterMonthPlanDao;
import com.gdssoft.pdaweb.dao.water.WaterMeterMonthPlanReadDao;
import com.gdssoft.pdaweb.dao.water.WaterMeterPlanDao;
import com.gdssoft.pdaweb.model.am.AmMonthPlan;
import com.gdssoft.pdaweb.model.am.AmMonthPlanRead;
import com.gdssoft.pdaweb.model.am.AmPlan;
import com.gdssoft.pdaweb.model.am.PdaAmMeterList;
import com.gdssoft.pdaweb.model.water.PdaWaterList;
import com.gdssoft.pdaweb.model.water.WaterMeterMonthPlan;
import com.gdssoft.pdaweb.model.water.WaterMeterMonthPlanRead;
import com.gdssoft.pdaweb.model.water.WaterMeterPlan;
import com.gdssoft.pdaweb.service.am.PdaAmMeterListService;
import com.gdssoft.pdaweb.service.water.PdaWaterListService;

public class MeterRecordSyncJob {

	private transient final Log logger = LogFactory.getLog(getClass());

	private AmPlanDao amPlanDao;
	private AmMonthPlanDao amMonthPlanDao;
	private AmMonthPlanReadDao amMonthPlanReadDao;
	private PdaAmMeterListDao pdaAmMeterListDao;

	private WaterMeterMonthPlanDao waterMeterMonthPlanDao;
	private WaterMeterMonthPlanReadDao waterMeterMonthPlanReadDao;
	private WaterMeterPlanDao waterMeterPlanDao;
	private PdaWaterListDao pdaWaterListDao;
	
	@Resource
	private PdaAmMeterListService pdaAmMeterListService;
	@Resource
	private PdaWaterListService pdaWaterListService;

	public MeterRecordSyncJob() {
	}

	public void doJob() {
		logger.info("MeterRecordSyncJob execute begin");

		syncAmMeterRecord();

		syncWaterMeterRecord();

		logger.info("MeterRecordSyncJob executed end");
	}

	/**
	 * 同步水表抄表读数
	 */
	private void syncWaterMeterRecord() {
		List<WaterMeterPlan> listWateMerter = waterMeterPlanDao.listOpeningPlans();
		
		logger.info("执行中的计划数：" + listWateMerter.size());

		for (int i = 0; i < listWateMerter.size(); i++) {
			boolean isAllWaterManthPlanClosed = true;
			long planId = listWateMerter.get(i).getPlanId();
			
			List<WaterMeterMonthPlan> listWaterMeterMonth = waterMeterMonthPlanDao
					.getByIdAndStatus(planId, (long) 1);
			
			logger.info("计划  " + planId + "，执行中的月度计划数量：" 
					+ listWaterMeterMonth.size());
			
			for (int j = 0; j < listWaterMeterMonth.size(); j++) {
				WaterMeterMonthPlan waterMeterMonthPlan = listWaterMeterMonth
						.get(j);
				Date EndTime = listWaterMeterMonth.get(j).getEndTime();// 计划结束时间
				String EndTimeStr = DateUtil.dateFormat(EndTime, "yyyy-MM-dd");
				
				String Month = listWaterMeterMonth.get(j).getMonth();// 抄表月份

				logger.info("-- 月度计划 " + waterMeterMonthPlan.getMpId() 
						+ "，抄表月份：" + waterMeterMonthPlan);

				String NowTime = DateUtil.dateFormat(new Date(), "yyyy-MM-dd");// 系统时间
				
				if (EndTimeStr.equals(NowTime)) {
					List<WaterMeterMonthPlanRead> listWaterMeterMonthReadDegree = 
							waterMeterMonthPlanReadDao.getByIdAndMonth(planId, Month);
					for (int k = 0; k < listWaterMeterMonthReadDegree.size(); k++) {
						WaterMeterMonthPlanRead waterMeterMonthPlanRead = listWaterMeterMonthReadDegree.get(k);
						mergeWaterMeterList(waterMeterMonthPlanRead);
					}
					// planId相同的所有月计划关闭了，才关闭计划id为planId的总计划
					isAllWaterManthPlanClosed = isAllWaterManthPlanClosed
							&& closeWaterMonthPlan(waterMeterMonthPlan
									.getMpId());
				} else {
					isAllWaterManthPlanClosed = false;
					logger.info("---- 计划未到期，结束日期：" + EndTime);
				}
			}
			if (isAllWaterManthPlanClosed) {
				closeWaterPlan(planId);
				logger.info("关闭 " + planId);
			} else {
				logger.info("存在未关闭的月度计划，还不能关闭");
			}
			logger.info("--------------------------------------------------");
		}

	}

	/**
	 * 将水表月计划读书表中的记录同步至水表历史记录表
	 * 
	 * @param amMonthPlan
	 */
	private void mergeWaterMeterList(
			WaterMeterMonthPlanRead waterMeterMonthPlanRead) {
		
		logger.info(" ---- 更新抄表历史记录，参数：" + 
				waterMeterMonthPlanRead.toString());
			
		PdaWaterList pdaWaterList = pdaWaterListDao.getWaterListByMeterIDAndMonth(
						waterMeterMonthPlanRead.getMeterID(),
						waterMeterMonthPlanRead.getMonth());

		if (null == pdaWaterList) {
			pdaWaterList = new PdaWaterList();
			logger.debug(" ---- 新的读数记录：" + waterMeterMonthPlanRead.getMeterID() 
					+ ", " + waterMeterMonthPlanRead.getMonth());
		}

		pdaWaterList.setAmId(waterMeterMonthPlanRead.getMeterID());
		pdaWaterList.setDegree(waterMeterMonthPlanRead.getDegree());
		pdaWaterList.setMonth(waterMeterMonthPlanRead.getMonth());
		if (waterMeterMonthPlanRead.getReadingTime() == null) {
			pdaWaterList.setRecordTime(null);
			pdaWaterList.setRecorderId(null);
		} else {
			pdaWaterList.setRecorderId(waterMeterMonthPlanRead.getExecutor());
			pdaWaterList.setRecordTime(waterMeterMonthPlanRead.getReadingTime());
		}
		pdaWaterList.setUpdateDate(null);
		pdaWaterList.setRemark(null);
		pdaWaterList.setCreateddt(new Date().toString());
		pdaWaterList.setCreatedby(waterMeterMonthPlanRead.getCreatedby());
		pdaWaterList.setLasteditdt(new Date().toString());
		pdaWaterList.setLasteditby(waterMeterMonthPlanRead.getLastEditBy());
		
		String status = pdaWaterListService.checkNomal(

				waterMeterMonthPlanRead.getMeterID(),
				waterMeterMonthPlanRead.getDegree(),
				waterMeterMonthPlanRead.getMonth());
		
		pdaWaterList.setStatus(status);
		pdaWaterList.setToCrmFlag(0);

		pdaWaterListDao.merge(pdaWaterList);

	}

	/**
	 * 关闭水表的月计划
	 * 
	 * @param mpId
	 *            月计划的主键
	 */
	private boolean closeWaterMonthPlan(Long mpId) {
		WaterMeterMonthPlan waterMeterMonth = waterMeterMonthPlanDao.get(mpId);
		// WaterMeterMonthPlan waterMeterMonthPlan = listWaterMeterMonth.get(0);
		waterMeterMonth.setPlanStatus((long) 0);
		waterMeterMonth.setLastEditBy("system");
		waterMeterMonth.setLastEditDt(new Date());
		waterMeterMonthPlanDao.saveOrUpdate(waterMeterMonth);

		logger.info(" -- 关闭月度计划 " + mpId);

		WaterMeterMonthPlan result = waterMeterMonthPlanDao.get(mpId);
		
		return result.getPlanStatus().equals(0L);
	}

	/**
	 * 关闭水表总计划
	 * 
	 * @param planId
	 *            总计划的Id
	 */
	private void closeWaterPlan(Long planId) {
		WaterMeterPlan waterMeterPlan = waterMeterPlanDao.get(planId);
		waterMeterPlan.setPlanStatus((long) 0);
		waterMeterPlan.setLastEditBy("system");
		waterMeterPlan.setLastEditDt(new Date());
		waterMeterPlanDao.saveOrUpdate(waterMeterPlan);
	}

	/**
	 * 同步电表抄表读数@Transactional
	 */
	private void syncAmMeterRecord() {
		List<AmPlan> listAmPlan = amPlanDao.listOpeningPlans();
		
		logger.info("执行中的计划数：" + listAmPlan.size());
		
		for (int i = 0; i < listAmPlan.size(); i++) {
			boolean isAllAmManthPlanClosed = true;
			Long planId = listAmPlan.get(i).getPlanId();

			List<AmMonthPlan> listAmMonthPlan = amMonthPlanDao.listByIdStatus(planId, 1L);
			
			logger.info("计划  " + planId + "，执行中的月度计划数量：" 
					+ listAmMonthPlan.size());

			for (int j = 0; j < listAmMonthPlan.size(); j++) {
				AmMonthPlan amMonthPlan = listAmMonthPlan.get(j);
				String month = listAmMonthPlan.get(j).getMonth();// 抄表月份

				logger.info("-- 月度计划 " + amMonthPlan.getMpId() + "，抄表月份：" + month);
					
				String EndTime = DateUtil.dateFormat(amMonthPlan.getEndTime(), 
						"yyyy-MM-dd");
				
				String NowTime = DateUtil.dateFormat(new Date(), "yyyy-MM-dd");
				
				if (NowTime.equals(EndTime)){
					// 同步合并电表抄表月计划读数到历史记录表
					List<AmMonthPlanRead> listAmMonthPlanRead = 
							amMonthPlanReadDao.listReadByIdMonth(planId, month);
					
					for (int m = 0; m < listAmMonthPlanRead.size(); m++){
						AmMonthPlanRead amMonthPlanRead = listAmMonthPlanRead.get(m);
						mergeAmMeterList(amMonthPlanRead);
					}
					// planId相同的所有月计划关闭了，才关闭计划id为planId的总计划
					isAllAmManthPlanClosed = isAllAmManthPlanClosed
							&& closeAmMonthPlan(amMonthPlan.getMpId());
				} else {
					isAllAmManthPlanClosed = false;
					logger.info("---- 计划未到期，结束日期：" + EndTime);
				}
			} 
			
			if (isAllAmManthPlanClosed) {
				closeAmPlan(planId);
				logger.info("关闭 " + planId);
			} else {
				logger.info("存在未关闭的月度计划，还不能关闭");
			}
			logger.info("--------------------------------------------------");
		}
	}

	/**
	 * 插入/更新电表抄表历史记录
	 * 
	 * @param amMonthPlan
	 */
	private void mergeAmMeterList(AmMonthPlanRead amMonthPlanRead) 
	{
		logger.info(" ---- 更新抄表历史记录，参数：" + amMonthPlanRead.toString());
		
		PdaAmMeterList pdaAmList = pdaAmMeterListDao.getAmListByMeterIDAndMonth(
				amMonthPlanRead.getMeterId(), amMonthPlanRead.getMonth());

		if (null == pdaAmList) {
			pdaAmList = new PdaAmMeterList();
			logger.debug(" ---- 新的读数记录：" + amMonthPlanRead.getMeterId() 
					+ ", " + amMonthPlanRead.getMonth());
		}

		pdaAmList.setAmId(amMonthPlanRead.getMeterId());
		pdaAmList.setDegree(amMonthPlanRead.getDegree());

		pdaAmList.setMonth(amMonthPlanRead.getMonth());
		if (amMonthPlanRead.getReadingTime() == null) {
			pdaAmList.setRecordtime(null);
			pdaAmList.setRecorderId(null);
		} else {
			pdaAmList.setRecorderId(amMonthPlanRead.getExecutor());
			pdaAmList.setRecordtime(amMonthPlanRead.getReadingTime());
		}
		pdaAmList.setUpdataid(amMonthPlanRead.getLastEditBy());
		pdaAmList.setUpdatedate(amMonthPlanRead.getUploadTime());
		pdaAmList.setRemark(null);
		pdaAmList.setCreateddt(new Date().toString());
		pdaAmList.setCreatedby(amMonthPlanRead.getLastEditBy());
		pdaAmList.setLasteditby(amMonthPlanRead.getLastEditBy());
		pdaAmList.setLasteditdt(new Date().toString());
		//String status=pdaWaterListService.checkNomal(amMonthPlanRead.getMeterId(), amMonthPlanRead.getDegree(), amMonthPlanRead.getMonth());
		String status = pdaAmMeterListService.checkNomal(amMonthPlanRead.getMeterId(), amMonthPlanRead.getDegree(), amMonthPlanRead.getMonth());
		pdaAmList.setStatus(status);
		pdaAmList.setToCrmFlag(0);
		pdaAmMeterListDao.merge(pdaAmList);
	}

	/**
	 * 关闭电表抄表月计划
	 * 
	 * @param mpId
	 */
	private boolean closeAmMonthPlan(Long mpId) {
		AmMonthPlan amMonthPlan = amMonthPlanDao.get(mpId);
		amMonthPlan.setPlanStatus((long) 0);
		amMonthPlan.setLastEditBy("system");
		amMonthPlan.setLastEditDt(new Date());
		amMonthPlanDao.saveOrUpdate(amMonthPlan);
		
		logger.info(" -- 关闭月度计划 " + mpId);
		
		AmMonthPlan result = amMonthPlanDao.get(mpId);
		
		return result.getPlanStatus().equals(0L);
	}

	/**
	 * 关闭电表抄表总计划
	 * 
	 * @param planId
	 */
	private void closeAmPlan(Long planId) {
		AmPlan amPlan = amPlanDao.get(planId);
		amPlan.setPlanStatus((long) 0);
		amPlan.setLastEditBy("system");
		amPlan.setLastEditDt(new Date());
		amPlanDao.saveOrUpdate(amPlan);
	}

	public void setAmPlanDao(AmPlanDao amPlanDao) {
		this.amPlanDao = amPlanDao;
	}

	public void setAmMonthPlanDao(AmMonthPlanDao amMonthPlanDao) {
		this.amMonthPlanDao = amMonthPlanDao;
	}

	public void setAmMonthPlanReadDao(AmMonthPlanReadDao amMonthPlanReadDao) {
		this.amMonthPlanReadDao = amMonthPlanReadDao;
	}

	public void setPdaAmMeterListDao(PdaAmMeterListDao pdaAmMeterListDao) {
		this.pdaAmMeterListDao = pdaAmMeterListDao;
	}

	public void setWaterMeterMonthPlanDao(
			WaterMeterMonthPlanDao waterMeterMonthPlanDao) {
		this.waterMeterMonthPlanDao = waterMeterMonthPlanDao;
	}

	public void setWaterMeterMonthPlanReadDao(
			WaterMeterMonthPlanReadDao waterMeterMonthPlanReadDao) {
		this.waterMeterMonthPlanReadDao = waterMeterMonthPlanReadDao;
	}

	public void setWaterMeterPlanDao(WaterMeterPlanDao waterMeterPlanDao) {
		this.waterMeterPlanDao = waterMeterPlanDao;
	}

	public void setPdaWaterListDao(PdaWaterListDao pdaWaterListDao) {
		this.pdaWaterListDao = pdaWaterListDao;
	}

}
